<template>
  <el-card>
    <el-form
      ref="formRef"
      label-width="100"
      :model="spuFormData"
      :rules="spuFormDataRules"
    >
      <el-form-item label="SPU名称" prop="spuName">
        <el-input placeholder="SPU名称" v-model="spuFormData.spuName" />
      </el-form-item>
      <el-form-item label="品牌" prop="tmId">
        <el-select placeholder="请选择" v-model="spuFormData.tmId">
          <el-option
            v-for="tradeMark in tradeMarkList"
            :key="tradeMark.id"
            :label="tradeMark.tmName"
            :value="tradeMark.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述" prop="description">
        <el-input
          type="textarea"
          placeholder="SPU描述"
          v-model="spuFormData.description"
          :autosize="{ minRows: 4, maxRows: 6 }"
        />
      </el-form-item>
      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          list-type="picture-card"
          :on-exceed="handleExceed"
          :limit="MAX__UPLOAD__NUMBER"
          accept="image/jpeg, image/png"
          :on-success="handleAvatarSuccess"
          :on-preview="handlePictureCardPreview"
          :before-upload="handleBeforePictureUpload"
          v-model:file-list="spuFormData.spuImageList"
          :action="`${BaseURL}/admin/product/fileUpload`"
        >
          <el-icon><Plus /></el-icon>
          <template #tip>
            <div class="el-upload__tip">只能上传jpg/png文件，且不超过200kb</div>
          </template>
        </el-upload>
        <el-dialog v-model="dialogVisible">
          <img
            w-full
            alt="预览图片"
            :src="dialogImageUrl"
            class="addOrUpdateSpu__previewImage"
          />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select
          v-model="selectedBaseSaleAttr"
          :placeholder="placeholderMessage"
          class="mr-10 mb-20"
        >
          <el-option
            :key="baseSaleAttr.id"
            :value="`${baseSaleAttr.id}:${baseSaleAttr.name}`"
            :label="baseSaleAttr.name"
            v-for="baseSaleAttr in filteredBaseSaleAttrList"
          />
        </el-select>
        <el-button
          class="mb-20"
          type="primary"
          @click="addSaleAttr"
          :disabled="!selectedBaseSaleAttr"
          >添加销售属性</el-button
        >
        <el-table
          :data="spuFormData.spuSaleAttrList"
          border
          style="width: 100%"
        >
          <el-table-column
            label="序号"
            type="index"
            width="80"
            align="center"
          ></el-table-column>
          <el-table-column
            label="属性名"
            width="150"
            prop="saleAttrName"
          ></el-table-column>
          <el-table-column label="属性值名称列表">
            <template v-slot="{ row }">
              <el-tag
                v-for="(spuSaleAttrValue, index) in row.spuSaleAttrValueList"
                :key="spuSaleAttrValue.saleAttrValueName"
                class="mx-1 mr-10"
                type="success"
                closable
                :disable-transitions="false"
                @close="deleteSpuSaleAttrValue(row.spuSaleAttrValueList, index)"
              >
                {{ spuSaleAttrValue.saleAttrValueName }}
              </el-tag>
              <el-input
                v-if="row.isShowEdit"
                ref="InputRef"
                class="addOrUpdate__input--text"
                size="small"
                v-model="attrValueName"
                @blur="hiddenEdit(row)"
                @keyup.enter="hiddenEdit(row)"
              />
              <el-button
                v-else
                class="button-new-tag ml-1"
                size="small"
                @click="showEdit(row)"
              >
                +
              </el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150">
            <template v-slot="{ row, $index }">
              <el-popconfirm
                :title="`你确定要删除${row.saleAttrName}销售属性吗？`"
                @confirm="delSaleAttr($index)"
              >
                <template #reference>
                  <el-button
                    title="删除"
                    size="small"
                    type="danger"
                    :icon="Delete"
                  />
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">保存</el-button>
        <el-button @click="cancel">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "addOrUpdateSpu",
};
</script>

<script lang="ts" setup>
import { ref, nextTick, reactive, computed, onMounted } from "vue";
import { ElInput, ElMessage } from "element-plus";
import { Plus, Delete } from "@element-plus/icons-vue";
import type { UploadProps } from "element-plus";
import {
  addSpuListApi,
  getTrademarkListApi,
  getBaseSaleAttrListApi,
  getSpuImageListApi,
  getSpuSaleAttrListApi,
  updateSpuListApi,
} from "@/api/product/spu";
import type {
  SpuFormData,
  SpuSaleAttrList,
  SpuSaleAttrItem,
  GetBaseSaleAttrList,
  SpuSaleAttrValueList,
} from "@/api/product/model/spuModel";
import type { TrademarkList } from "@/api/product/model/trademarkModel";
import { useCategoryStore } from "@/stores/category";
import { useSpuStore } from "@/stores/spu";
/*******************************标签相关**************************************/
const InputRef = ref();
const attrValueName = ref("");
// 显示输入框
const showEdit = async (row: SpuSaleAttrItem) => {
  row.isShowEdit = true;
  // 自动获取焦点
  await nextTick();
  InputRef.value.focus();
};
// 隐藏输入框
const hiddenEdit = (row: SpuSaleAttrItem) => {
  row.isShowEdit = false;
  // 判断是否为空值或者为重复的值
  if (!attrValueName.value) return;
  if (
    row.spuSaleAttrValueList.some((spuSaleAttrValue) => {
      return spuSaleAttrValue.saleAttrValueName === attrValueName.value;
    })
  ) {
    ElMessage.warning("请不要添加重复的属性值名称!");
    attrValueName.value = "";
    return;
  }
  //将input收集到的数据添加到数组中去
  row.spuSaleAttrValueList.push({
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: attrValueName.value,
  });
  //清除input收集到的值
  attrValueName.value = "";
  // 展示tag标签
};
// 删除tag标签
const deleteSpuSaleAttrValue = (
  spuSaleAttrValueList: SpuSaleAttrValueList,
  index: number
) => {
  spuSaleAttrValueList.splice(index, 1);
};

/**********************************************************************************/
const BaseURL = import.meta.env.VITE_API_URL;
// 获取表单实例(使用表单上的属性和方法)
const formRef = ref();
// 定义表单数据
const spuStore = useSpuStore();
const spuFormData = reactive<SpuFormData>({
  spuName: spuStore.spu.spuName,
  tmId: spuStore.spu.tmId,
  description: spuStore.spu.description,
  spuImageList: [],
  spuSaleAttrList: [],
});
// 图片等数据需要发送请求获得
// 因此定义接口数据
// 获取图片列表，如果没有ID就不发送请求
onMounted(async () => {
  const id = spuStore.spu.id;
  if (!id) return;
  const spuImageList = await getSpuImageListApi(id as number);
  spuFormData.spuImageList = spuImageList.map((spuImage) => {
    return {
      name: spuImage.imgName,
      url: spuImage.imgUrl,
      response: {
        data: spuImage.imgUrl,
      },
    };
  });
});
// 获取销售属性列表，如果没有ID就不发送请求
onMounted(async () => {
  const id = spuStore.spu.id;
  if (!id) return;
  const spuSaleAttrList = await getSpuSaleAttrListApi(id as number);
  spuFormData.spuSaleAttrList = spuSaleAttrList;
});
// 校验表单
const categoryStore = useCategoryStore();
const onSubmit = async () => {
  await formRef.value.validate();
  const id = spuStore.spu.id;
  const data = {
    category3Id: categoryStore.category3Id,
    ...spuFormData,
    spuImageList: spuFormData.spuImageList.map((spuImage) => {
      return {
        imgName: spuImage.name,
        imgUrl: (spuImage.response as { data: string }).data,
      };
    }),
  };
  if (id) {
    await updateSpuListApi({
      ...data,
      id,
    });
  } else {
    await addSpuListApi(data);
  }
  ElMessage.success(`${id ? "更新" : "添加"}SPU成功`);
  cancel();
};
// 上传图片成功之后清除图片校验
const handleAvatarSuccess = () => {
  formRef.value.clearValidate(["spuImageList"]);
};
// 自定义校验规则
const spuSaleAttrListValidator = (
  rule: any,
  value: SpuSaleAttrList,
  callback: any
) => {
  if (!value.length) {
    callback(new Error("请至少添加一个销售属性"));
    return;
  }
  if (!value.every((spuSaleAttr) => spuSaleAttr.spuSaleAttrValueList.length)) {
    callback(new Error("每个销售属性请至少添加一个销售属性值"));
    return;
  }
  callback();
};
// 制定表单校验规则
const spuFormDataRules = reactive({
  spuName: [{ required: true, message: "请输入SPU名称", trigger: "blur" }],
  tmId: [{ required: true, message: "请选择SPU品牌", trigger: "change" }],
  description: [{ required: true, message: "请输入SPU描述", trigger: "blur" }],
  spuImageList: [{ required: true, message: "请上传SPU图片" }],
  spuSaleAttrList: [
    {
      required: true,
      validator: spuSaleAttrListValidator,
    },
  ],
});
/****************************************************************************/
const tradeMarkList = ref<TrademarkList>([]);
const baseSaleAttrList = ref<GetBaseSaleAttrList>([]);
// const filteredBaseSaleAttrList = ref<GetBaseSaleAttrList>([]);
onMounted(async () => {
  const res = await getTrademarkListApi();
  tradeMarkList.value = res;
});
onMounted(async () => {
  const res = await getBaseSaleAttrListApi();
  baseSaleAttrList.value = res;
});
//删除销售属性
const delSaleAttr = (index: number) => {
  spuFormData.spuSaleAttrList.splice(index, 1);
};
//
const placeholderMessage = computed(() => {
  return filteredBaseSaleAttrList.value.length
    ? `还有${filteredBaseSaleAttrList.value.length}未选择`
    : "没有啦~~";
});
// 计算baseSaleAttrList
const filteredBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((baseSaleAttr) => {
    return !spuFormData.spuSaleAttrList.some(
      (spuSaleAttr) => baseSaleAttr.id === spuSaleAttr.baseSaleAttrId
    );
  });
});
// 收集select的数据
const selectedBaseSaleAttr = ref("");
// 点击添加销售属性按钮
const addSaleAttr = () => {
  // 通过:分割获取到的值
  const [id, name] = selectedBaseSaleAttr.value.split(":");
  // 被选中的数据存放至spuSaleAttrList数组中
  spuFormData.spuSaleAttrList.push({
    baseSaleAttrId: +id,
    saleAttrName: name,
    spuSaleAttrValueList: [],
    isShowEdit: false,
  });
  // 清空ID
  selectedBaseSaleAttr.value = "";
};
/********************************上传图片相关*********************************/
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
// 图片数量限制相关
const MAX__UPLOAD__NUMBER = 10;
const isUploadHidden = computed(() => {
  return spuFormData.spuImageList.length < MAX__UPLOAD__NUMBER
    ? "inline-flex"
    : "none";
});
const handleExceed: UploadProps["onExceed"] = () => {
  ElMessage.warning(`上传图片数量不能超过${MAX__UPLOAD__NUMBER}张`);
};
// 上传文件之前的钩子，参数为上传的文件， 若返回false或者返回 Promise 且被 reject，则停止上传。
const handleBeforePictureUpload: UploadProps["beforeUpload"] = (rawFile) => {
  const typeList = ["image/jpeg", "image/png"];
  if (!typeList.includes(rawFile.type)) {
    ElMessage.error("图片格式必须是jpeg或png格式");
    return false;
  } else if (rawFile.size / 1024 > 200) {
    ElMessage.error("图片大小不能超过200KB!");
    return false;
  }
  return true;
};
// 点击文件列表中已上传的文件时的钩子
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url as string;
  dialogVisible.value = true;
};
// 点击取消按钮
const emit = defineEmits(["setIsShow"]);
const cancel = () => {
  emit("setIsShow", 1);
};
</script>

<style scoped>
:deep(.el-upload) {
  display: v-bind(isUploadHidden);
}
.addOrUpdateSpu__previewImage {
  width: 100%;
}
.addOrUpdate__input--text {
  width: 120px;
}
</style>
